package com.lambkit.core.loadbalance;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 轮询（Round Robin）<br/>
 * 轮询算法按照顺序将新的请求分配给下一个服务器，最终实现平分请求。<br/>
 * <br/>
 * 优点：<br/>
 * 实现简单，无需记录各种服务的状态，是一种无状态的负载均衡策略。实现绝对公平 <br/>
 * <br/>
 * 缺点：<br/>
 * 当各个服务器性能不一致的情况，无法根据服务器性能去分配，无法合理利用服务器资源。<br/>
 * 
 * https://blog.csdn.net/mountain9527/article/details/119960229
 * @author yangyong
 *
 */
public class RoundRobin {
	
	private AtomicInteger NEXT_SERVER_COUNTER = new AtomicInteger(0);

    private int select(int modulo) {
        for (; ; ) {
            int current = NEXT_SERVER_COUNTER.get();
            int next = (current + 1) % modulo;
            boolean compareAndSet = NEXT_SERVER_COUNTER.compareAndSet(current, next);
            if (compareAndSet) {
                return next;
            }
        }
    }

    public Server selectServer(List<Server> serverList) {
        return serverList.get(select(serverList.size()));
    }

    public static void main(String[] args) {
        List<Server> serverList = new ArrayList<>();
        serverList.add(new Server(1, "服务器1"));
        serverList.add(new Server(2, "服务器2"));
        serverList.add(new Server(3, "服务器3"));
        RoundRobin lb = new RoundRobin();
        for (int i = 0; i < 10; i++) {
            Server selectedServer = lb.selectServer(serverList);
            System.out.format("第%d次请求，选择服务器%s\n", i + 1, selectedServer.toString());

        }
    }
}
